package vn.demand.dragon.editor
{
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.TextEvent;
	
	import mx.controls.TextInput;

	public class FormattedNumberInput extends TextInput
	{
		[Bindable] public var str:String = "";
		[Bindable] public var value:Number;
		[Bindable] public var formattedValue:String = "";
		
		public function FormattedNumberInput()
		{
			super();
			addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
			
			addEventListener(Event.CHANGE, onChange);
			addEventListener(flash.events.TextEvent.TEXT_INPUT, onTextInput);
		}

		protected function onChange(e:Event):void {
//			RIALogger.debug(this, "onChange: " + text);
			text = formattedValue;
		}
		
		protected function onTextInput(e:TextEvent):void {
//			RIALogger.debug(this, "onTextInput: " + e.text);
			e.preventDefault();
		}
		
		
		protected function onKeyDown(e:KeyboardEvent):void {
			var oldIndex:int = selectionBeginIndex;
			var newIndex:int = 0;
			var ch:String = numToChar(e.charCode);
			var ignore:Boolean = (ch == "");
			switch (e.keyCode) {
				case 37://LEFT
					newIndex = oldIndex > 0 ? (oldIndex - 1) : 0;
					selectionBeginIndex = newIndex;
					selectionEndIndex = newIndex;
					return;
				case 39://RIGHT
					newIndex = oldIndex < text.length ? (oldIndex + 1) : text.length;
					selectionBeginIndex = newIndex;
					selectionEndIndex = newIndex;
					return;
				case 38://UP
					selectionBeginIndex = 0;
					selectionEndIndex = 0;
					return;
				case 40://END
					selectionBeginIndex = text.length;
					selectionEndIndex = text.length;
					return;
				case 46://DELETE
					if (oldIndex == text.length) {
						return;
					}
					if (formattedValue.charAt(oldIndex) == ",") {
						selectionBeginIndex = int(oldIndex + 1); 
						selectionEndIndex = int(oldIndex + 1); 
						return;
					}
					ch = formattedValue.charAt(oldIndex - 1);
					if (ch == ",") {
						ch = formattedValue.charAt(oldIndex - 2);
						formattedValue = formattedValue.substring(0, oldIndex - 2) + formattedValue.substring(oldIndex + 1);
						oldIndex = oldIndex - 2;
					}
					else {
						formattedValue = formattedValue.substring(0, oldIndex - 1) + formattedValue.substring(oldIndex + 1);
						oldIndex = oldIndex - 1;
					}
					ignore = false;
					break;
				case 8://BACKSPACE
					if (oldIndex == 0) {
						return;
					}
					if (formattedValue.charAt(oldIndex - 1) == ",") {
						selectionBeginIndex = int(oldIndex - 1); 
						selectionEndIndex = int(oldIndex - 1); 
						return;
					}
					
					if (oldIndex - 2 < 0) {
						if (formattedValue.charAt(oldIndex) == ",") {
							ch = formattedValue.charAt(oldIndex + 1);
							formattedValue = formattedValue.substring(oldIndex + 2);
							oldIndex = 0;
						} else {
							ch = "";
							formattedValue = formattedValue.substring(oldIndex);
							oldIndex = 0;
						}
					} else {
						ch = formattedValue.charAt(oldIndex - 2);
						if (ch == ",") {
							ch = formattedValue.charAt(oldIndex - 3);
							formattedValue = formattedValue.substring(0, oldIndex - 3) + formattedValue.substring(oldIndex);
							oldIndex = oldIndex - 3;
						}
						else {
							formattedValue = formattedValue.substring(0, oldIndex - 2) + formattedValue.substring(oldIndex);
							RIALogger.debug(this, "backspace, ch: " + ch);
							RIALogger.debug(this, "backspace, formatValue: " + formattedValue);
							oldIndex = oldIndex - 2;
							RIALogger.debug(this, "backspace, oldIndex: " + oldIndex);
						}	
					}
					ignore = false;
					break;
			}
			if (ignore) {
				return;
			}
			e.preventDefault();
			if (ch == "-" || ch == "+") {
				if (oldIndex != 0) {
					return;
				}
				if (formattedValue.charAt(0) == "+" || formattedValue.charAt(0) == "-") {
					formattedValue = formattedValue.slice(1);
				}
				formattedValue = ch + formattedValue; 
				text = formattedValue;
				selectionBeginIndex = 1;
				selectionEndIndex = 1;
				return;
			}
			if (!allowChar(ch, oldIndex)) {
				return;
			}
			
			if (selectionEndIndex > selectionBeginIndex) {
				formattedValue = formattedValue.slice(0, selectionBeginIndex) + formattedValue.slice(selectionEndIndex);
			}
			
			var tmp:String = null;
			tmp = formattedValue.substring(0, oldIndex) + "x" + formattedValue.substring(oldIndex);
			
			formattedValue = format(tmp, ch);
			
			newIndex = formattedValue.lastIndexOf("x") + 1;
			selectionBeginIndex = newIndex;
			selectionEndIndex = newIndex;
			
			formattedValue = formattedValue.replace("x", ch);
			text = formattedValue;
		}
		
		private function numToChar(num:int):String {
	        switch (num) {
	        	case 46: return ".";
	        	case 43: return "+";
	        	case 45: return "-";
	        }
	        if (num > 47 && num < 58) {
	            var strNums:String = "0123456789";
	            return strNums.charAt(num - 48);
	        } else if (num > 64 && num < 91) {
	            var strCaps:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	            return strCaps.charAt(num - 65);
	        } else if (num > 96 && num < 123) {
	            var strLow:String = "abcdefghijklmnopqrstuvwxyz";
	            return strLow.charAt(num - 97);
	        } else {
	        	RIALogger.debug(this, "keycode dat bit: " + num);
	            return "";
	        }
    	}  
		
		private function allowChar(ch:String, curIndex:int):Boolean {
			var num:int = ch.charCodeAt(0);
			if (num > 47 && num < 58) {
				if (curIndex == 0 && (formattedValue.charAt(0) == "+" || formattedValue.charAt(0) == "-")) {
					return false;
				}
				return true;
			}
			switch (num) {
	        	case 46: 
	        		if (formattedValue.lastIndexOf(".") >= 0) {
	        			return false;
	        		}
	        		return true;
	        	case 43: 
	        	case 45: 
	        		if (curIndex != 0) {
	        			return false;
	        		}
	        		return true;
	        }
	        return false;
		}
		
		public function format(rawStr:String, charCode:String):String {
			RIALogger.debug(this, "format rawStr: " + rawStr);
			var result:String = "";
			var sign:String = "";
			if (rawStr.charAt(0) == "+" || rawStr.charAt(0) == "-") {
				sign = rawStr.charAt(0);
				rawStr = rawStr.slice(1);
			}
			var startIndex:int = rawStr.lastIndexOf(".");
			if (charCode == ".") {
				startIndex = rawStr.length - 1;
			}
			if (startIndex < 0) {
				startIndex = rawStr.length - 1;
			} else {
				result = rawStr.slice(startIndex);
				rawStr = rawStr.slice(0, startIndex);
				startIndex = rawStr.length - 1;
			}
			
			var k:int = 0;
			for(var i:int = startIndex; i >=0 ; i--) {
				var ch:String = rawStr.charAt(i);
				if (ch == ",") {
					continue;
				}
				result = ch + result;
				k++;
				if (i > 0 && (k % 3 == 0) && ch != "-" && ch != "+") {
					result = "," + result; 
				}
			}
			return sign + result;
		}
	}
}